package ui.swing.textcomponent;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.UndoableEdit;

public class TextArea_UndoRedo extends JFrame implements UndoableEditListener{

	private UndoableEdit undoEdit;
	private JTextArea jta;
	private JTextArea message;
	private JMenuItem undoItem;
	private JMenuItem redoItem;
	
	public TextArea_UndoRedo() {
		super("TextArea Demo");
		setBounds(100, 100, 680, 540);
		
		jta = new JTextArea();
		jta.getDocument().addUndoableEditListener(this);
		
		message = new JTextArea();
		message.setEditable(false); // message不可编辑
		
		JPanel p1 = new JPanel();
		p1.setLayout(new GridLayout(1, 1));
		p1.setBorder(BorderFactory.createTitledBorder("Edit Area"));
		p1.add(new JScrollPane(jta));
		
		JPanel p2 = new JPanel();
		p2.setLayout(new GridLayout(1, 1));
		p2.setBorder(BorderFactory.createTitledBorder("Message"));
		p2.add(new JScrollPane(message));
		
		getContentPane().setLayout(new GridLayout(2,1));
    	getContentPane().add(p1);
    	getContentPane().add(p2);
    	
    	JMenuBar bar  = new JMenuBar();
    	JMenu theMenu = new JMenu("Edit");
    	undoItem = new JMenuItem("Undo");
    	redoItem = new JMenuItem("Redo");
    	theMenu.add(undoItem);
    	theMenu.add(redoItem);
    	bar.add(theMenu);
    	setJMenuBar(bar);
    	
    	updateMenuItem(); // 构造目录菜单
    	
    	undoItem.addActionListener(new ActionListener(){
    		public void actionPerformed(ActionEvent ev){
    			undoEdit.undo();
    			updateMenuItem();//运行undo功能
    			message.append("- Undo -\n");
    		}	
    	});

    	redoItem.addActionListener(new ActionListener(){
    		public void actionPerformed(ActionEvent ev){
    			undoEdit.redo();
    			updateMenuItem();//运行redo功能
    			message.append("- Redo -\n");
    		}	
    	}); 
    	
    	setDefaultCloseOperation(EXIT_ON_CLOSE);
    	setVisible(true);
	}
	
	public void updateMenuItem() {
		if(undoEdit != null) {
			undoItem.setEnabled(undoEdit.canUndo());
			redoItem.setEnabled(undoEdit.canRedo());
			undoItem.setText(undoEdit.getUndoPresentationName());
			redoItem.setText(undoEdit.getRedoPresentationName());
		} else {
			undoItem.setEnabled(false);
			redoItem.setEnabled(false);
			undoItem.setText("Undo");
			redoItem.setText("Redo");
		}
	} //end of updateMenu()

    public void undoableEditHappened(UndoableEditEvent ev){
    	StringBuffer buf = new StringBuffer(200);
         /*当用户在Text Area中有所操作时，就可以用getEdit()方法取得UndoableEdit对象，此对象纪录着刚刚用户的操作，因
          *此可由些对象的undo()或redo()达到取消或复原的功能.
          */
    	undoEdit = ev.getEdit();
    	buf.append("undoableEdit:");
    	buf.append(undoEdit.getPresentationName());
    	buf.append("\n");
    	message.append(buf.toString());
    	updateMenuItem();
    }//end of undoableEditHappened()

    public static void main(String[] args) {
		new TextArea_UndoRedo();
	}
	
}
